home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr49 / vesa18.zip / PMSCREEN.C < prev    next >
C/C++ Source or Header  |  1994-10-08  |  30KB  |  763 lines

  1. /* VESA package for emx/gcc --- Copyright (c) 1993 by Johannes Martin */
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <sys/hw.h>
  6.  
  7. #define INCL_WIN
  8. #define INCL_DOSQUEUES
  9. #define INCL_DOSPROCESS
  10. #define INCL_DOSFILEMGR
  11. #define INCL_DOSSEMAPHORES
  12. #define INCL_VIO
  13. #define INCL_AVIO
  14.  
  15. #define PAL_COUNT 256
  16. #define TEXT_COLS 80
  17. #define TEXT_ROWS 25
  18.  
  19. #include <os2emx.h>
  20. #include <os2thunk.h>
  21.  
  22. #include "vesa_pm.h"
  23. #include "pmscreen.h"
  24.  
  25. typedef struct
  26.   {
  27.     BOOL   UsePalette;
  28.     BOOL   UseFullPalette;
  29.     BOOL   OriginalSize;
  30.     USHORT Intervall;
  31.     USHORT x, y;
  32.   } PRFDATA;
  33.  
  34. static DATABUFFER *DataBuffer;
  35. static HPIPE      hpipe1, hpipe2, hpipe3, hpipe4;
  36. static BOOL       UsePalette;
  37. static BOOL       UseFullPalette;
  38. static BOOL       OriginalSize;
  39. static BOOL       HasPalMan;
  40. static USHORT     Intervall;
  41. static USHORT     XChar, YChar;
  42.  
  43. BOOL ReadIniData(BOOL General)
  44. {
  45.   PRFDATA PrfData;
  46.   ULONG   size;
  47.  
  48.   size = sizeof(PRFDATA);
  49.   if (PrfQueryProfileData(HINI_PROFILE, "PMSCREEN",
  50.                           General ? "GENERAL" : DataBuffer->ProgName,
  51.                           &PrfData, &size) && (size == sizeof(PRFDATA)))
  52.     {
  53.       UsePalette     = PrfData.UsePalette;
  54.       UseFullPalette = PrfData.UseFullPalette;
  55.       OriginalSize   = PrfData.OriginalSize;
  56.       Intervall      = PrfData.Intervall;
  57.       XChar          = PrfData.x;
  58.       YChar          = PrfData.y;
  59.       return(TRUE);
  60.     }
  61.   return(FALSE);
  62. }
  63.  
  64. MRESULT SettingsDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  65. {
  66.   switch (msg)
  67.     {
  68.       case WM_INITDLG:
  69.         {
  70.           WinSendMsg(WinWindowFromID(hwnd, DID_XSIZE), EM_SETTEXTLIMIT, MPFROMSHORT(2), NULL);
  71.           WinSendMsg(WinWindowFromID(hwnd, DID_YSIZE), EM_SETTEXTLIMIT, MPFROMSHORT(2), NULL);
  72.           if (DataBuffer)
  73.             {
  74.               CHAR str[3];
  75.  
  76.               WinEnableWindow(WinWindowFromID(hwnd, DID_USEPAL), HasPalMan && (DataBuffer->bits <= 8));
  77.               WinEnableWindow(WinWindowFromID(hwnd, DID_FULLPAL), HasPalMan && UsePalette);
  78.               WinSetDlgItemShort(hwnd, DID_INTERVALL, Intervall, FALSE);
  79.               WinCheckButton(hwnd, DID_USEPAL, UsePalette);
  80.               WinCheckButton(hwnd, DID_FULLPAL, UseFullPalette);
  81.               WinCheckButton(hwnd, DID_ORGSIZE, OriginalSize);
  82.               _itoa(YChar, str, 10);
  83.               WinSetDlgItemText(hwnd, DID_YSIZE, str);
  84.               _itoa(XChar, str, 10);
  85.               WinSetDlgItemText(hwnd, DID_XSIZE, str);
  86.             }
  87.           else
  88.             {
  89.               WinSetDlgItemShort(hwnd, DID_INTERVALL, 3000, FALSE);
  90.               WinEnableWindow(WinWindowFromID(hwnd, DID_FULLPAL), FALSE);
  91.               WinSetDlgItemText(hwnd, DID_YSIZE, "1");
  92.               WinSetDlgItemText(hwnd, DID_XSIZE, "1");
  93.               WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
  94.               WinEnableWindow(WinWindowFromID(hwnd, DID_APPDEF), FALSE);
  95.             }
  96.           return(0);
  97.         }
  98.       case WM_CONTROL:
  99.         switch(SHORT2FROMMP(mp1))
  100.           {
  101.             case BN_CLICKED:
  102.               if (SHORT1FROMMP(mp1) == DID_USEPAL)
  103.                 {
  104.                   ULONG State = !WinQueryButtonCheckstate(hwnd, DID_USEPAL);
  105.                   WinCheckButton(hwnd, DID_USEPAL, State);
  106.                   WinEnableWindow(WinWindowFromID(hwnd, DID_FULLPAL), State);
  107.                 }
  108.               break;
  109.           }
  110.         break;
  111.       case WM_COMMAND:
  112.         switch (COMMANDMSG(&msg)->cmd)
  113.           {
  114.             case DID_OK:
  115.               {
  116.                 CHAR str[3];
  117.  
  118.                 WinQueryDlgItemShort(hwnd, DID_INTERVALL, &Intervall, FALSE);
  119.                 UsePalette     = WinQueryButtonCheckstate(hwnd, DID_USEPAL);
  120.                 UseFullPalette = WinQueryButtonCheckstate(hwnd, DID_FULLPAL);
  121.                 OriginalSize   = WinQueryButtonCheckstate(hwnd, DID_ORGSIZE);
  122.                 WinQueryDlgItemText(hwnd, DID_YSIZE, 3, str);
  123.                 YChar = atoi(str);
  124.                 WinQueryDlgItemText(hwnd, DID_XSIZE, 3, str);
  125.                 XChar = atoi(str);
  126.                 WinDismissDlg(hwnd, TRUE);
  127.                 return(0);
  128.               }
  129.             case DID_CANCEL:
  130.               WinDismissDlg(hwnd, FALSE);
  131.               return(0);
  132.             case DID_APPDEF:
  133.             case DID_SYSDEF:
  134.               {
  135.                 PRFDATA PrfData;
  136.                 CHAR str[3];
  137.  
  138.                 WinQueryDlgItemShort(hwnd, DID_INTERVALL, &PrfData.Intervall, FALSE);
  139.                 PrfData.UsePalette     = WinQueryButtonCheckstate(hwnd, DID_USEPAL);
  140.                 PrfData.UseFullPalette = WinQueryButtonCheckstate(hwnd, DID_FULLPAL);
  141.                 PrfData.OriginalSize   = WinQueryButtonCheckstate(hwnd, DID_ORGSIZE);
  142.                 WinQueryDlgItemText(hwnd, DID_YSIZE, 3, str);
  143.                 PrfData.y = atoi(str);
  144.                 WinQueryDlgItemText(hwnd, DID_XSIZE, 3, str);
  145.                 PrfData.x = atoi(str);
  146.                 PrfWriteProfileData(HINI_PROFILE, "PMSCREEN",
  147.                                     COMMANDMSG(&msg)->cmd == DID_SYSDEF ? "GENERAL" : DataBuffer->ProgName,
  148.                                     &PrfData, sizeof(PRFDATA));
  149.               }
  150.               if (!DataBuffer)
  151.                 WinDismissDlg(hwnd, TRUE);
  152.               return(0);
  153.           }
  154.         break;
  155.     }
  156.   return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  157. }
  158.  
  159. void WriteChar(USHORT usCode)
  160. {
  161.   ULONG written;
  162.  
  163.   if ((usCode & 0x00FF) == 0)
  164.     {
  165.       DosWrite(hpipe2, &usCode, sizeof(CHAR), &written);
  166.       usCode >>= 8;
  167.       DosWrite(hpipe2, &usCode, sizeof(CHAR), &written);
  168.     }
  169.   else
  170.     {
  171.       DosWrite(hpipe1, &usCode, sizeof(CHAR), &written);
  172.       DosWrite(hpipe2, &usCode, sizeof(CHAR), &written);
  173.     }
  174. }
  175.  
  176. void InstallMenu(HWND hwnd)
  177. {
  178.   CHAR *szMenuText[3] = { NULL, "~Update screen", "~PM-Screen settings" };
  179.   MENUITEM mi[3]      = {{ MIT_END, MIS_SEPARATOR, 0, 0, (HWND) NULL, (ULONG) NULL },
  180.                          { MIT_END, MIS_TEXT, 0, IDM_UPDATE, (HWND) NULL, (ULONG) NULL },
  181.                          { MIT_END, MIS_TEXT, 0, IDM_SETTINGS, (HWND) NULL, (ULONG) NULL }};
  182.   HWND     hwndSysMenu, hwndSysSubMenu;
  183.   MENUITEM miSysMenu;
  184.   SHORT    sItem, idSysMenu;
  185.  
  186.   hwndSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), FID_SYSMENU);
  187.   idSysMenu   = SHORT1FROMMR(WinSendMsg(hwndSysMenu, MM_ITEMIDFROMPOSITION, NULL, NULL));
  188.   WinSendMsg(hwndSysMenu, MM_QUERYITEM,  MPFROM2SHORT(idSysMenu, FALSE), MPFROMP(&miSysMenu));
  189.   hwndSysSubMenu = miSysMenu.hwndSubMenu;
  190.   for (sItem = 0; sItem < 3; sItem++)
  191.      WinSendMsg(hwndSysSubMenu, MM_INSERTITEM, MPFROMP(mi+sItem), MPFROMP(szMenuText[sItem]));
  192. }
  193.  
  194. BOOL TestPalMan(HDC hdc)
  195. {
  196.   ULONG caps;
  197.  
  198.   DevQueryCaps(hdc, CAPS_ADDITIONAL_GRAPHICS, 1, &caps);
  199.   return((caps & CAPS_PALETTE_MANAGER) != 0);
  200. }
  201.  
  202. VOID MakePalette(HWND hwnd, HPS hps, HPAL *hPal)
  203. {
  204.   ULONG i, color;
  205.   ULONG alTable[PAL_COUNT];
  206.  
  207.   for (i = 0; i < PAL_COUNT; i++)
  208.     alTable[i] = PC_RESERVED * 16777216
  209.                + DataBuffer->bmi.argbColor[i].bRed * 65536
  210.                + DataBuffer->bmi.argbColor[i].bGreen * 256
  211.                + DataBuffer->bmi.argbColor[i].bBlue;
  212.  
  213.   *hPal = GpiCreatePalette(WinQueryAnchorBlock(hwnd),
  214.                            LCOL_PURECOLOR | (UseFullPalette ? LCOL_OVERRIDE_DEFAULT_COLORS : 0),
  215.                            LCOLF_CONSECRGB, PAL_COUNT, alTable);
  216.   GpiSelectPalette(hps, *hPal);
  217.   WinRealizePalette(hwnd, hps, &color);
  218. }
  219.  
  220. VOID RemovePalette(HPS hps, HPAL *hPal)
  221. {
  222.   GpiSelectPalette(hps, 0);
  223.   GpiDeletePalette(*hPal);
  224.   *hPal = 0;
  225. }
  226.  
  227. MRESULT GraphWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  228. {
  229.   static BOOL do_update;
  230.   static HMTX hmtxPS;
  231.   static HPS  hpsBuffer;
  232.   static HPAL hPal;
  233.   static HDC  hdc;
  234.  
  235.   switch (msg)
  236.     {
  237.       case WM_CREATE:
  238.         {
  239.           SIZEL sizl = { 0L, 0L };
  240.           HAB   hab;
  241.  
  242.           DosCreateMutexSem(NULL, &hmtxPS, 0, FALSE);
  243.           hab       = WinQueryAnchorBlock(hwnd);
  244.           hdc       = WinOpenWindowDC(hwnd);
  245.           hpsBuffer = GpiCreatePS(hab, hdc, &sizl, PU_PELS | GPIF_DEFAULT |
  246.                                   GPIT_MICRO | GPIA_ASSOC );
  247.           DataBuffer->hwndGraph = hwnd;
  248.           DataBuffer->modified  = TRUE;
  249.           HasPalMan             = TestPalMan(hdc);
  250.           if (!ReadIniData(FALSE) && !ReadIniData(TRUE))
  251.             {
  252.               UsePalette            = FALSE;
  253.               UseFullPalette        = FALSE;
  254.               OriginalSize          = FALSE;
  255.               Intervall             = 3000;
  256.               XChar                 = 1;
  257.               YChar                 = 1;
  258.             }
  259.           do_update             = TRUE;
  260.           hPal                  = 0;
  261.           InstallMenu(hwnd);
  262.           WinStartTimer(hab, hwnd, ID_TIMER, Intervall);
  263.           WinPostMsg(DataBuffer->hwndText, WM_FONTSIZECHANGED, NULL, NULL);
  264.           break;
  265.         }
  266.       case WM_CHAR:
  267.         {
  268.           if (CHARMSG(&msg)->fs & KC_KEYUP)
  269.             return(0);
  270.           if (CHARMSG(&msg)->fs & KC_CHAR)
  271.             {
  272.               WriteChar(CHARMSG(&msg)->chr);
  273.               return(0);
  274.             }
  275.           if (CHARMSG(&msg)->fs & KC_VIRTUALKEY)
  276.             {
  277.               static USHORT keytable[][5] = {
  278.                 /* VK-Keyword  normal- shifted- ctrl-  alt- Code */
  279.                 { VK_ESC,      0x001b, 0x001b, 0x001b, 0x001b },
  280.                 { VK_BACKTAB,  0x0f00, 0x0f00, 0x0f00, 0x0f00 },
  281.                 { VK_PAGEUP,   0x4900, 0x0039, 0x8400, 0x9900 },
  282.                 { VK_PAGEDOWN, 0x5100, 0x0033, 0x7600, 0xa100 },
  283.                 { VK_END,      0x4f00, 0x0031, 0x7500, 0x9f00 },
  284.                 { VK_HOME,     0x4700, 0x0037, 0x7700, 0x9700 },
  285.                 { VK_LEFT,     0x4b00, 0x0034, 0x7300, 0x9b00 },
  286.                 { VK_UP,       0x4800, 0x0038, 0x8D00, 0x9800 },
  287.                 { VK_RIGHT,    0x4d00, 0x0036, 0x7400, 0x9d00 },
  288.                 { VK_DOWN,     0x5000, 0x0032, 0x9100, 0xa000 },
  289.                 { VK_INSERT,   0x5200, 0x0030, 0x9200, 0xa200 },
  290.                 { VK_DELETE,   0x5300, 0x002e, 0x9300, 0xa300 },
  291.                 { VK_F1,       0x3b00, 0x5400, 0x5e00, 0x6800 },
  292.                 { VK_F2,       0x3c00, 0x5500, 0x5f00, 0x6900 },
  293.                 { VK_F3,       0x3d00, 0x5600, 0x6000, 0x6a00 },
  294.                 { VK_F4,       0x3e00, 0x5700, 0x6100, 0x6b00 },
  295.                 { VK_F5,       0x3f00, 0x5800, 0x6200, 0x6c00 },
  296.                 { VK_F6,       0x4000, 0x5900, 0x6300, 0x6d00 },
  297.                 { VK_F7,       0x4100, 0x5a00, 0x6400, 0x6e00 },
  298.                 { VK_F8,       0x4200, 0x5b00, 0x6500, 0x6f00 },
  299.                 { VK_F9,       0x4300, 0x5c00, 0x6600, 0x7000 },
  300.                 { VK_F10,      0x4400, 0x5d00, 0x6700, 0x7100 },
  301.                 { VK_F11,      0x8500, 0x8700, 0x8900, 0x8b00 },
  302.                 { VK_F12,      0x8600, 0x8800, 0x8a00, 0x8c00 },
  303.                 { 0,           0,      0,      0,      0      } };
  304.               int i = 0;
  305.  
  306.               while (keytable[i][0] != 0)
  307.                 {
  308.                   if (keytable[i][0] == CHARMSG(&msg)->vkey)
  309.                     {
  310.                       if (CHARMSG(&msg)->fs & KC_ALT)
  311.                         WriteChar(keytable[i][4]);
  312.                       else if (CHARMSG(&msg)->fs & KC_CTRL)
  313.                         WriteChar(keytable[i][3]);
  314.                       else if (CHARMSG(&msg)->fs & KC_SHIFT)
  315.                         WriteChar(keytable[i][2]);
  316.                       else
  317.                         WriteChar(keytable[i][1]);
  318.                       return(0);
  319.                     }
  320.                   i++;
  321.                 }
  322.               return(0);
  323.             }
  324.           if ((CHARMSG(&msg)->fs & KC_CTRL) && (CHARMSG(&msg)->chr != 0))
  325.             {
  326.               WriteChar(CHARMSG(&msg)->chr & 0x1f);
  327.               return(0);
  328.             }
  329.           if ((CHARMSG(&msg)->fs & KC_SCANCODE) &&
  330.               (CHARMSG(&msg)->fs & KC_ALT))
  331.             {
  332.               WriteChar(CHARMSG(&msg)->scancode << 8);
  333.               return(0);
  334.             }
  335.           return(0);
  336.         }
  337.       case WM_COMMAND:
  338.         switch (COMMANDMSG(&msg) -> cmd)
  339.           {
  340.             case IDM_SETTINGS:
  341.               {
  342.                 static BOOL inDlg = 0;
  343.                 ULONG rc;
  344.  
  345.                 if (inDlg)
  346.                   return(0);
  347.                 inDlg = 1;
  348.                 rc = WinDlgBox(HWND_DESKTOP, hwnd, SettingsDlgProc, 0, ID_SETTINGS, NULL);
  349.                 inDlg = 0;
  350.                 if (rc)
  351.                   {
  352.                     SWP swp;
  353.  
  354.                     WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER);
  355.                     WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER, Intervall);
  356.                     if (hPal)
  357.                       RemovePalette(hpsBuffer, &hPal);
  358.  
  359.                     WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT), &swp);
  360.                     if (((swp.fl & SWP_MINIMIZE) == 0) && OriginalSize &&
  361.                         ((DataBuffer->pointl[1].y != DataBuffer->pointl[3].y - 1) ||
  362.                          (DataBuffer->pointl[1].x != DataBuffer->pointl[3].x - 1)))
  363.                       {
  364.                         RECTL rectl;
  365.  
  366.                         rectl.xLeft   = 0;
  367.                         rectl.yBottom = 0;
  368.                         rectl.xRight  = DataBuffer->pointl[3].x;
  369.                         rectl.yTop    = DataBuffer->pointl[3].y;
  370.                         WinCalcFrameRect(WinQueryWindow(hwnd, QW_PARENT), &rectl, FALSE);
  371.                         WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), 0, 0, 0,
  372.                                         rectl.xRight - rectl.xLeft - 1,
  373.                                         rectl.yTop   - rectl.yBottom - 1, SWP_SIZE);
  374.                       }
  375.                     WinPostMsg(DataBuffer->hwndText, WM_FONTSIZECHANGED, NULL, NULL);
  376.                   }
  377.                 else
  378.                   return(0);
  379.               }
  380.             case IDM_UPDATE:
  381.               WinInvalidateRect(hwnd, NULL, FALSE);
  382.               return(0);
  383.           }
  384.         break;
  385.       case WM_DONTUPDATE:
  386.         do_update = FALSE;
  387.         DosPostEventSem(DataBuffer->hev);
  388.         return(0);
  389.       case WM_NEWMODE:
  390.         DataBuffer->bmi.cbFix           = 64;
  391.         DataBuffer->bmi.cx              = DataBuffer->pointl[3].x;
  392.         DataBuffer->bmi.cy              = DataBuffer->pointl[3].y;
  393.         DataBuffer->bmi.cPlanes         = 1;
  394.         DataBuffer->bmi.cBitCount       = DataBuffer->bits;
  395.         DataBuffer->bmi.ulCompression   = BCA_UNCOMP;
  396.         DataBuffer->bmi.cbImage         = 0;
  397.         DataBuffer->bmi.cxResolution    = 2000;
  398.         DataBuffer->bmi.cyResolution    = 2000;
  399.         DataBuffer->bmi.cclrUsed        = 0;
  400.         DataBuffer->bmi.cclrImportant   = 0;
  401.         DataBuffer->bmi.usUnits         = BRU_METRIC;
  402.         DataBuffer->bmi.usReserved      = 0;
  403.         DataBuffer->bmi.usRecording     = BRA_BOTTOMUP;
  404.         DataBuffer->bmi.usRendering     = BRH_NOTHALFTONED;
  405.         DataBuffer->bmi.cSize1          = 0;
  406.         DataBuffer->bmi.cSize2          = 0;
  407.         DataBuffer->bmi.ulColorEncoding = BCE_RGB;
  408.         DataBuffer->bmi.ulIdentifier    = 0;
  409.         if (DataBuffer->GraphBuffer != 0)
  410.           {
  411.             HWND temp1, temp2;
  412.  
  413.             DosGetSharedMem(DataBuffer->GraphBuffer, PAG_READ);
  414.             WinSetWindowPos(temp1 = WinQueryWindow(DataBuffer->hwndText, QW_PARENT),
  415.                             0, 0, 0, 0, 0, SWP_SHOW | SWP_MINIMIZE);
  416.             WinSetWindowPos(temp2 = WinQueryWindow(DataBuffer->hwndGraph, QW_PARENT),
  417.                             0, 0, 0, 0, 0, SWP_SHOW | SWP_RESTORE);
  418.             if (WinQueryActiveWindow(HWND_DESKTOP) == temp1)
  419.               WinSetActiveWindow(HWND_DESKTOP, temp2);
  420.           }
  421.         else
  422.           {
  423.             HWND temp1, temp2;
  424.  
  425.             WinSetWindowPos(temp1 = WinQueryWindow(DataBuffer->hwndGraph, QW_PARENT),
  426.                             0, 0, 0, 0, 0, SWP_SHOW | SWP_MINIMIZE);
  427.             WinSetWindowPos(temp2 = WinQueryWindow(DataBuffer->hwndText, QW_PARENT),
  428.                             0, 0, 0, 0, 0, SWP_SHOW | SWP_RESTORE);
  429.             if (WinQueryActiveWindow(HWND_DESKTOP) == temp1)
  430.               WinSetActiveWindow(HWND_DESKTOP, temp2);
  431.           }
  432.         if (DataBuffer->bits > 8)
  433.           UsePalette = FALSE;
  434.         DataBuffer->mousex      = 0;
  435.         DataBuffer->mousey      = 0;
  436.         DataBuffer->mousestatus = 0;
  437.       case WM_UPDATE:
  438.         do_update = TRUE;
  439.         DataBuffer->modified = TRUE;
  440.         WinInvalidateRect(hwnd, NULL, FALSE);
  441.         return(0);
  442.       case WM_CHGPALETTE:
  443.         if (hPal)
  444.           {
  445.             ULONG i;
  446.             ULONG alTable[PAL_COUNT];
  447.  
  448.             for (i = 0; i < PAL_COUNT; i++)
  449.               alTable[i] = PC_RESERVED * 16777216
  450.                          + DataBuffer->bmi.argbColor[i].bRed * 65536
  451.                          + DataBuffer->bmi.argbColor[i].bGreen * 256
  452.                          + DataBuffer->bmi.argbColor[i].bBlue;
  453.             WinRequestMutexSem(hmtxPS, SEM_INDEFINITE_WAIT);
  454.             GpiAnimatePalette(hPal, LCOLF_CONSECRGB, 0, PAL_COUNT, alTable);
  455.             DosReleaseMutexSem(hmtxPS);
  456.           }
  457.         else
  458.           DataBuffer->modified = TRUE;
  459.         DosPostEventSem(DataBuffer->hev);
  460.         return(0);
  461.       case WM_SIZE:
  462.         {
  463.           SWP swp;
  464.  
  465.           WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT), &swp);
  466.           DataBuffer->pointl[1].x = SHORT1FROMMP(mp2);
  467.           DataBuffer->pointl[1].y = SHORT2FROMMP(mp2);
  468.           if (((swp.fl & SWP_MINIMIZE) == 0) && OriginalSize &&
  469.               ((DataBuffer->pointl[1].y != DataBuffer->pointl[3].y - 1) ||
  470.                (DataBuffer->pointl[1].x != DataBuffer->pointl[3].x - 1)))
  471.             {
  472.               RECTL rectl;
  473.  
  474.               rectl.xLeft   = 0;
  475.               rectl.yBottom = 0;
  476.               rectl.xRight  = DataBuffer->pointl[3].x;
  477.               rectl.yTop    = DataBuffer->pointl[3].y;
  478.               WinCalcFrameRect(WinQueryWindow(hwnd, QW_PARENT), &rectl, FALSE);
  479.               WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), 0, swp.x,
  480.                               swp.y + swp.cy - rectl.yTop + rectl.yBottom + 1,
  481.                               rectl.xRight - rectl.xLeft - 1,
  482.                               rectl.yTop   - rectl.yBottom - 1, SWP_SIZE | SWP_MOVE);
  483.             }
  484.           else
  485.             WinInvalidateRect(hwnd, NULL, FALSE);
  486.         }
  487.         break;
  488.       case WM_TIMER:
  489.         if (do_update && DataBuffer->modified)
  490.           WinInvalidateRect(hwnd, NULL, FALSE);
  491.         break;
  492.       case WM_PAINT:
  493.         {
  494.           HPS hps;
  495.  
  496.           WinRequestMutexSem(hmtxPS, SEM_INDEFINITE_WAIT);
  497.           if (UsePalette && !hPal)
  498.             MakePalette(hwnd, hpsBuffer, &hPal);
  499.           else
  500.             if (hPal && !UsePalette)
  501.               RemovePalette(hpsBuffer, &hPal);
  502.           hps = WinBeginPaint(hwnd, hpsBuffer, NULL);
  503.           if (do_update && (DataBuffer->GraphBuffer != NULL))
  504.             {
  505.               GpiDrawBits(hps, DataBuffer->GraphBuffer, (PVOID) &DataBuffer->bmi,
  506.                           4, DataBuffer->pointl, ROP_SRCCOPY, BBO_IGNORE);
  507.               DataBuffer->modified = FALSE;
  508.             }
  509.           else
  510.             GpiErase(hps);
  511.           WinEndPaint(hps);
  512.           DosReleaseMutexSem(hmtxPS);
  513.         }
  514.         return(0);
  515.       case WM_REALIZEPALETTE:
  516.         if (hPal)
  517.           {
  518.             ULONG cclr;
  519.  
  520.             WinRequestMutexSem(hmtxPS, SEM_INDEFINITE_WAIT);
  521.             WinRealizePalette(hwnd, hpsBuffer, &cclr);
  522.             DosReleaseMutexSem(hmtxPS);
  523.           }
  524.         break;
  525.       case WM_FINISH:
  526.         WinPostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_QUIT, NULL, NULL);
  527.         return(0);
  528.       case WM_CLOSE:
  529.         if (WinMessageBox(HWND_DESKTOP, hwnd, "Are you sure?", "Close Window?",
  530.                           0, MB_YESNO | MB_ICONQUESTION) == MBID_YES)
  531.           WinPostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_QUIT, NULL, NULL);
  532.         return(0);
  533.       case WM_DESTROY:
  534.         WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER);
  535.         if (hPal)
  536.           RemovePalette(hpsBuffer, &hPal);
  537.         if (hpsBuffer)
  538.           WinReleasePS(hpsBuffer);
  539.         break;
  540.     }
  541.   if (DataBuffer->GraphBuffer != NULL)
  542.     switch (msg)
  543.       {
  544.         case WM_MOUSEMOVE:
  545.           DataBuffer->mousex       =  1 + (ULONG) SHORT1FROMMP(mp1) * (ULONG) (DataBuffer->pointl[3].x) / (ULONG) (DataBuffer->pointl[1].x + 1);
  546.           DataBuffer->mousey       = -1 + (ULONG) (DataBuffer->pointl[1].y + 1 - SHORT2FROMMP(mp1)) * (ULONG) (DataBuffer->pointl[3].y) / (ULONG) (DataBuffer->pointl[1].y + 1);
  547.           break;
  548.         case WM_BUTTON1DOWN:
  549.           DataBuffer->mousex       =  1 + (ULONG) SHORT1FROMMP(mp1) * (ULONG) (DataBuffer->pointl[3].x) / (ULONG) (DataBuffer->pointl[1].x + 1);
  550.           DataBuffer->mousey       = -1 + (ULONG) (DataBuffer->pointl[1].y + 1 - SHORT2FROMMP(mp1)) * (ULONG) (DataBuffer->pointl[3].y) / (ULONG) (DataBuffer->pointl[1].y + 1);
  551.           DataBuffer->mousestatus |= 1;
  552.           break;
  553.         case WM_BUTTON2DOWN:
  554.           DataBuffer->mousex       =  1 + (ULONG) SHORT1FROMMP(mp1) * (ULONG) (DataBuffer->pointl[3].x) / (ULONG) (DataBuffer->pointl[1].x + 1);
  555.           DataBuffer->mousey       = -1 + (ULONG) (DataBuffer->pointl[1].y + 1 - SHORT2FROMMP(mp1)) * (ULONG) (DataBuffer->pointl[3].y) / (ULONG) (DataBuffer->pointl[1].y + 1);
  556.           DataBuffer->mousestatus |= 2;
  557.           break;
  558.         case WM_BUTTON3DOWN:
  559.           DataBuffer->mousex       =  1 + (ULONG) SHORT1FROMMP(mp1) * (ULONG) (DataBuffer->pointl[3].x) / (ULONG) (DataBuffer->pointl[1].x + 1);
  560.           DataBuffer->mousey       = -1 + (ULONG) (DataBuffer->pointl[1].y + 1 - SHORT2FROMMP(mp1)) * (ULONG) (DataBuffer->pointl[3].y) / (ULONG) (DataBuffer->pointl[1].y + 1);
  561.           DataBuffer->mousestatus |= 4;
  562.           break;
  563.         case WM_BUTTON1UP:
  564.           DataBuffer->mousex       =  1 + (ULONG) SHORT1FROMMP(mp1) * (ULONG) (DataBuffer->pointl[3].x) / (ULONG) (DataBuffer->pointl[1].x + 1);
  565.           DataBuffer->mousey       = -1 + (ULONG) (DataBuffer->pointl[1].y + 1 - SHORT2FROMMP(mp1)) * (ULONG) (DataBuffer->pointl[3].y) / (ULONG) (DataBuffer->pointl[1].y + 1);
  566.           DataBuffer->mousestatus &= ~1;
  567.           break;
  568.         case WM_BUTTON2UP:
  569.           DataBuffer->mousex       =  1 + (ULONG) SHORT1FROMMP(mp1) * (ULONG) (DataBuffer->pointl[3].x) / (ULONG) (DataBuffer->pointl[1].x + 1);
  570.           DataBuffer->mousey       = -1 + (ULONG) (DataBuffer->pointl[1].y + 1 - SHORT2FROMMP(mp1)) * (ULONG) (DataBuffer->pointl[3].y) / (ULONG) (DataBuffer->pointl[1].y + 1);
  571.           DataBuffer->mousestatus &= ~2;
  572.           break;
  573.         case WM_BUTTON3UP:
  574.           DataBuffer->mousex       =  1 + (ULONG) SHORT1FROMMP(mp1) * (ULONG) (DataBuffer->pointl[3].x) / (ULONG) (DataBuffer->pointl[1].x + 1);
  575.           DataBuffer->mousey       = -1 + (ULONG) (DataBuffer->pointl[1].y + 1 - SHORT2FROMMP(mp1)) * (ULONG) (DataBuffer->pointl[3].y) / (ULONG) (DataBuffer->pointl[1].y + 1);
  576.           DataBuffer->mousestatus &= ~4;
  577.           break;
  578.       }
  579.   return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  580. }
  581.  
  582. void ProcessOutput(HPIPE hpipe, ULONG MsgId)
  583. {
  584.   ULONG read;
  585.   CHAR  buffer[80];
  586.  
  587.   while (!DosRead(hpipe, buffer, sizeof(buffer), &read))
  588.     WinPostMsg(DataBuffer->hwndText, MsgId, MPFROMLONG(read), MPFROMP(buffer));
  589. }
  590.  
  591. void StdOutThread(ULONG x)
  592. {
  593.   ProcessOutput(hpipe3, WM_NEWCHAR);
  594. }
  595.  
  596. void StdErrThread(ULONG x)
  597. {
  598.   ProcessOutput(hpipe4, WM_NEWCHAR);
  599. }
  600.  
  601. MRESULT TextWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  602. {
  603.   static HPS  hps;
  604.   static HVPS hvps;
  605.  
  606.   switch (msg)
  607.     {
  608.       case WM_CREATE:
  609.         {
  610.           HDC   hdc;
  611.           SIZEL sizel;
  612.  
  613.           DataBuffer->hwndText    = hwnd;
  614.           InstallMenu(hwnd);
  615.  
  616.           hdc = WinOpenWindowDC(hwnd);
  617.           sizel.cx = sizel.cy = 0;
  618.           hps = GpiCreatePS(WinQueryAnchorBlock(hwnd), hdc, &sizel,
  619.                             PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC);
  620.           VioCreatePS(&hvps, TEXT_ROWS, TEXT_COLS, 0, 1, 0);
  621.           VioAssociate(hdc, hvps);
  622.           return(0);
  623.         }
  624.       case WM_SIZE:
  625.         WinDefAVioWindowProc(hwnd, msg, LONGFROMMP(mp1), LONGFROMMP(mp2));
  626.         WinPostMsg(hwnd, WM_FONTSIZECHANGED, NULL, NULL);
  627.         return(0);
  628.       case WM_NEWCHAR:
  629.         VioWrtTTY(PVOIDFROMMP(mp2), LONGFROMMP(mp1), hvps);
  630.         return(0);
  631.       case WM_CHAR:
  632.         WinSendMsg(DataBuffer->hwndGraph, msg, mp1, mp2);
  633.         break;
  634.       case WM_COMMAND:
  635.         switch (COMMANDMSG(&msg) -> cmd)
  636.           {
  637.             case IDM_SETTINGS:
  638.               WinSendMsg(DataBuffer->hwndGraph, msg, mp1, mp2);
  639.               break;
  640.             case IDM_UPDATE:
  641.               WinInvalidateRect(hwnd, NULL, FALSE);
  642.               return(0);
  643.           }
  644.         break;
  645.       case WM_PAINT:
  646.         WinBeginPaint(hwnd, hps, NULL);
  647.         VioShowBuf(0, TEXT_ROWS * TEXT_COLS * 2, hvps);
  648.         WinEndPaint(hps);
  649.         return(0);
  650.       case WM_FONTSIZECHANGED:
  651.         {
  652.           SWP   swp;
  653.           RECTL rectl;
  654.  
  655.           VioSetDeviceCellSize(YChar, XChar, hvps);
  656.           VioGetDeviceCellSize(&YChar, &XChar, hvps);
  657.           WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT), &swp);
  658.           WinQueryWindowRect(hwnd, &rectl);
  659.           if (((swp.fl & SWP_MINIMIZE) == 0) &&
  660.               ((rectl.xRight - rectl.xLeft   > XChar * TEXT_COLS) ||
  661.                (rectl.yTop   - rectl.yBottom > YChar * TEXT_ROWS)))
  662.             {
  663.               rectl.xLeft   = 0;
  664.               rectl.yBottom = 0;
  665.               rectl.xRight  = XChar * TEXT_COLS + 4;
  666.               rectl.yTop    = YChar * TEXT_ROWS + 4;
  667.               WinCalcFrameRect(WinQueryWindow(hwnd, QW_PARENT), &rectl, FALSE);
  668.               WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), 0, 0, 0,
  669.                               rectl.xRight, rectl.yTop, SWP_SIZE);
  670.             }
  671.           WinInvalidateRect(hwnd, NULL, FALSE);
  672.           return(0);
  673.         }
  674.       case WM_CLOSE:
  675.         if (WinMessageBox(HWND_DESKTOP, hwnd, "Are you sure?", "Close Window?",
  676.                           0, MB_YESNO | MB_ICONQUESTION) == MBID_YES)
  677.           WinPostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_QUIT, NULL, NULL);
  678.         return(0);
  679.       case WM_DESTROY:
  680.         VioAssociate(0, hvps);
  681.         VioDestroyPS(hvps);
  682.         GpiDestroyPS(hps);
  683.         return(0);
  684.     }
  685.   return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  686. }
  687.  
  688. int main(int argc, char *argv[])
  689. {
  690.   HAB hab;
  691.   HMQ hmq;
  692.  
  693.   hab = WinInitialize(0);
  694.   hmq = WinCreateMsgQueue(hab, 0);
  695.   if (argc != 2)
  696.     {
  697.       DataBuffer = NULL;
  698.       WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, SettingsDlgProc,
  699.                 NULLHANDLE, ID_SETTINGS, NULL);
  700.     }
  701.   else
  702.     {
  703.       static CHAR  szGraphClass[] = "PMSCREEN_GRAPH";
  704.       static CHAR  szTextClass[]  = "PMSCREEN_TEXT";
  705.       static ULONG flFrameFlags   = FCF_TITLEBAR      | FCF_SYSMENU   |
  706.                                     FCF_SIZEBORDER    | FCF_MINMAX    |
  707.                                     FCF_SHELLPOSITION | FCF_TASKLIST  |
  708.                                     FCF_ICON;
  709.       TID   tid;
  710.       QMSG  qmsg;
  711.       HWND  hwndGraphFrame, hwndGraphClient;
  712.       HWND  hwndTextFrame, hwndTextClient;
  713.       ULONG action;
  714.  
  715.       DataBuffer = (DATABUFFER *) atoi(argv[1]);
  716.       DosGetSharedMem(DataBuffer, PAG_READ | PAG_WRITE);
  717.       WinRegisterClass(hab, szGraphClass, GraphWndProc, 0, 0);
  718.       WinRegisterClass(hab, szTextClass, TextWndProc, 0, 0);
  719.       hwndTextFrame  = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &flFrameFlags,
  720.                                           szTextClass, "PM-Screen Text Window",
  721.                                           0, 0, ID_PMSCREEN, &hwndTextClient);
  722.       hwndGraphFrame = WinCreateStdWindow(HWND_DESKTOP, 0, &flFrameFlags,
  723.                                           szGraphClass, "PM-Screen Graphics Window",
  724.                                           0, 0, ID_PMSCREEN, &hwndGraphClient);
  725.       WinSetWindowPos(hwndGraphFrame, 0, 0, 0, 0, 0, SWP_SHOW | SWP_MINIMIZE);
  726.       DosOpenEventSem(NULL, &DataBuffer->hev);
  727.       DosPostEventSem(DataBuffer->hev);
  728.       DosWaitNPipe(DataBuffer->Pipe1Name, -1);
  729.       DosOpen(DataBuffer->Pipe1Name, &hpipe1, &action, 0, FILE_NORMAL,
  730.               OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
  731.               OPEN_SHARE_DENYNONE | OPEN_ACCESS_WRITEONLY, NULL);
  732.       DosSetNPHState(hpipe1, NP_NOWAIT);
  733.       DosWaitNPipe(DataBuffer->Pipe2Name, -1);
  734.       DosOpen(DataBuffer->Pipe2Name, &hpipe2, &action, 0, FILE_NORMAL,
  735.               OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
  736.               OPEN_SHARE_DENYNONE | OPEN_ACCESS_WRITEONLY, NULL);
  737.       DosSetNPHState(hpipe2, NP_NOWAIT);
  738.       DosWaitNPipe(DataBuffer->Pipe3Name, -1);
  739.       DosOpen(DataBuffer->Pipe3Name, &hpipe3, &action, 0, FILE_NORMAL,
  740.               OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
  741.               OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL);
  742.       DosWaitNPipe(DataBuffer->Pipe4Name, -1);
  743.       DosOpen(DataBuffer->Pipe4Name, &hpipe4, &action, 0, FILE_NORMAL,
  744.               OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
  745.               OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL);
  746.       DosCreateThread(&tid, StdOutThread, 0, 0, 32768);
  747.       DosCreateThread(&tid, StdErrThread, 0, 0, 32768);
  748.       while (WinGetMsg(hab, &qmsg, 0, 0, 0))
  749.         WinDispatchMsg(hab, &qmsg);
  750.       DosPostEventSem(DataBuffer->hev);
  751.       DosCloseEventSem(DataBuffer->hev);
  752.       DosClose(hpipe1);
  753.       DosClose(hpipe2);
  754.       DosClose(hpipe3);
  755.       DosClose(hpipe4);
  756.       WinDestroyWindow(hwndGraphFrame);
  757.       WinDestroyWindow(hwndTextFrame);
  758.     }
  759.   WinDestroyMsgQueue(hmq);
  760.   WinTerminate(hab);
  761.   return(argc != 2);
  762. }
  763.